/**
 *			\author ITII - ISEN - P6
 *			\author Benjamin Mur
 *			\file TcpServer.cpp
 *			\version 0.1
 *			\date 06/09/2010
 */

#include <iostream>
#include <string>
#include <arpa/inet.h>
#include "TcpServer.h"

#define SOCKET_ERROR -1

using namespace std;

TcpServer::TcpServer(int port)
{
    _sock_err=0;

	_init = false;

    if(CreateSocket() != SOCKET_ERROR)
    {
        //sleep(1);
        cout << "Socket Created and Opened" << endl;

        if(ConfigSocket(port) != SOCKET_ERROR)
        {
            //sleep(1);
            cout << "Socket Setup Ok" << endl;
            //sleep(1);
            cout << "Listing Port " << port << " ..." << endl;

            if(listen(_sock, 5) != SOCKET_ERROR)
            {
                if(WaitingClient() != SOCKET_ERROR)
                {
                    //sleep(1);

                    cout << "A client is Connected with socket: " << _csock << "at " << inet_ntoa(_csockin.sin_addr) << "port " << htons(_csockin.sin_port)<< endl;
			_init = true;
                    //sleep(1);
                    //cout << "Closing server socket" << endl;
                    //CloseSocket(&_sock);
                    //sleep(1);
                    //cout << "Closing client socket" << endl;
                    //CloseSocket(&_csock);
                }
                else
                {
                    cerr << "Error: Problem in Client Connection" << endl;
                    _sock_err=-1;
                }
            }
            else
            {
                cerr << "Error: Problem in Listing Port" << endl;
                _sock_err=-1;
            }

        }
        else
        {
            cerr << "Error: Problem in Socket Setup" << endl;
            _sock_err=-1;
        }
    }
    else
    {
        cerr << "Error: Socket Not Created" << endl;
        _sock_err=-1;
    }
}

TcpServer::~TcpServer()
{
	CloseSocket(&_csock);
	CloseSocket(&_sock);
}

bool TcpServer::isInit() const
{
	return _init;
}


int TcpServer::CreateSocket()
{
    //sleep(1);

    cout << "Creating Socket..." << endl;

    return _sock=socket(AF_INET, SOCK_STREAM, 0);
}

int TcpServer::ConfigSocket(int port)
{
    //sleep(1);

    cout << "Socket Setup..." << endl;

    _sockin.sin_addr.s_addr = htonl(INADDR_ANY);  /* Adresse IP automatique */
    _sockin.sin_family = AF_INET;                 /* Protocole familial (IP) */
    _sockin.sin_port = htons(port);               /* Listage du port */

    return bind(_sock, (SOCKADDR*)&_sockin,_sizesock=sizeof(_sockin));
}

int TcpServer::WaitingClient()
{
    //sleep(1);

    cout << "Waiting for Client Connection..." << endl;

    return _csock = accept(_sock, (SOCKADDR*)&_csockin, &(_csizesock=sizeof(_csockin)));
}

void TcpServer::CloseSocket(SOCKET* sock)
{
    close(*sock);
}

int TcpServer::serverSend(char* buffer, int bufferSize)
{
	return send(_csock, buffer, bufferSize, 0);
}

int TcpServer::serverReceive(char* buffer, int bufferSize)
{
	return recv(_csock, buffer, bufferSize, 0);
}
